一个2016年afl的议题记录:BSidesSF 2016 - Fuzz Smarter, Not Harder (An afl-fuzz Primer) (Craig Young)

afl

插桩

image-20200524131059153

64kb的共享内存来储存

image-20200524131146794

界面解析

image-20200524130957172

15.jpg

① Process timing:Fuzzer运行时长、以及距离最近发现的路径、崩溃和挂起经过了多长时间。

② Overall results:Fuzzer当前状态的概述。

③ Cycle progress:我们输入队列的距离。

④ Map coverage:目标二进制文件中的插桩代码所观察到覆盖范围的细节。

⑤ Stage progress:Fuzzer现在正在执行的文件变异策略、执行次数和执行速度。

⑥ Findings in depth:有关我们找到的执行路径,异常和挂起数量的信息。

⑦ Fuzzing strategy yields:关于突变策略产生的最新行为和结果的详细信息。

⑧ Path geometry:有关Fuzzer找到的执行路径的信息。

⑨ CPU load:CPU利用率

快速起fuzz的例子

image-20200524154930223

image-20200524154937731

image-20200524155003088

输出路径的文件夹解析

image-20200524155044373

一些问题

image-20200524155512104

优化

并行fuzz

可以用afl-whatsup <output目录>查看状态

-M进行确定性测试(deterministic ),即对输入文件进行一些特殊而非随机的的变异

-S进行完全随机的变异。

image-20200524155912083

获取cpu的个数

image-20200524160410790

跨系统fuzz

https://github.com/MartijnB/disfuzz-afl

image-20200524160524230

提升效率

llvm模式会更快

image-20200527215339609

image-20200527215905030

持久模式

image-20200527220028278

两者相结合提速2.8倍

image-20200527220348762

大海捞针

减少单个输入的大小

image-20200527220550958

移除执行相同代码的输入文件

image-20200527220740091

给字典(关键字)

image-20200527221352848

去掉校验代码

image-20200527221527851

一个开源,一个不开源的同类软件

image-20200527221713538

crash 处理

image-20200527221932846

image-20200527221954175

找到那里导致的崩溃

image-20200527222128989

image-20200527222458471

Sanitizers

image-20200527222524597

image-20200527222810248

image-20200527222848257

作者自己的方法

image-20200527223024958

afl自带的一些工具

预处理

移除执行相同代码的输入文件——afl-cmin
减小单个输入文件的大小——afl-tmin

使用afl-showmap跟踪单个输入的执行路径,并打印程序执行的输出、捕获的元组(tuples),tuple用于获取分支信息,从而衡量衡量程序覆盖情况

fuzz状态查看

并行fuzz时,afl-whatsup工具可以查看每个fuzzer的运行状态和总体运行概况,加上-s选项只显示概况,其中的数据都是所有fuzzer的总和。

afl-gotcpu工具可以查看每个核心使用状态

afl-plot绘制各种状态指标的直观变化趋势图

崩溃处理

afl-fuzz -C - crash exploration mode (the peruvian rabbit thing).
AFL源码的experimental目录中有一个名为triage_crashes.sh的脚本,可以帮助我们触发收集到的crashes。

https://github.com/bnagy/crashwalk 工具基于gdb的exploitable插件

afl-collect,它也是afl-utils套件中的一个工具,同样也是基于exploitable来检查crashes的可利用性。它可以自动删除无效的crash样本、删除重复样本以及自动化样本分类。
afl-collect -j 8 -d crashes.db -e gdb_script ./afl_sync_dir ./collection_dir – /path/to/target –target-opts

其他人开发的工具

https://gitlab.com/rc0r/afl-utils

代码覆盖率

GCOV随gcc一起发布,所以不需要再单独安装,和afl-gcc插桩编译的原理一样,gcc编译时生成插桩的程序,用于在执行时生成代码覆盖率信息。

另外一个工具是LCOV,它是GCOV的图形前端,可以收集多个源文件的gcov数据,并创建包含使用覆盖率信息注释的源代码HTML页面。
最后一个工具是afl-cov,可以快速帮助我们调用前面两个工具处理来自afl-fuzz测试用例的代码覆盖率结果。

1
2
3
4
5
6
7
8
9
10
11
12
还是以Fuzz libtiff为例,计算Fuzzing过程的代码覆盖率流程如下:

第一步,使用gcov重新编译源码,在CFLAGS中添加"-fprofile-arcs"和"-ftest-coverage"选项,可以在--prefix中重新指定一个新的目录以免覆盖之前alf插桩的二进制文件。

$ make clean
$ ./configure --prefix=/root/tiff-4.0.10/build-cov CC="gcc" CXX="g++" CFLAGS="-fprofile-arcs -ftest-coverage" --disable-shared
$ make
$ make install
第二步,执行afl-cov。其中-d选项指定afl-fuzz输出目录;—live用于处理一个还在实时更新的AFL目录,当afl-fuzz停止时,afl-cov将退出;–enable-branch-coverage用于开启边缘覆盖率(分支覆盖率)统计;-c用于指定源码目录;最后一个-e选项用来设置要执行的程序和参数,其中的AFL_FILE和afl中的”@@”类似,会被替换为测试用例,LD_LIBRARY_PATH则用来指定程序的库文件。

$ cd ~/tiff-4.0.10
$ afl-cov -d ~/syncdir --live --enable-branch-coverage -c . -e "cat AFL_FILE | LD_LIBRARY_PATH=./build-cov/lib ./build-cov/bin/tiff2pdf AFL_FILE"

参考

https://www.youtube.com/watch?v=4IrYczT5YFs

打赏专区